import React, { PureComponent } from 'react'
import {
  Tabs, Menu, Dropdown, Tooltip,
} from 'antd'
import $ from 'jquery'
import { ResizableBox } from 'react-resizable'
import BaseTable, { AutoResizer, Column } from 'react-base-table'
import 'react-base-table/styles.css'
import { getProjectId } from '@/utils/https'
import Tools from '@/utils/Tools'
import styles from './index.less'

const Bus = Tools.Bus
const { TabPane } = Tabs

class LoggerTable extends PureComponent {
  render() {
    const { columns, rowData } = this.props
    const rowData2 = []
    rowData.slice(1).map((row, dataIndex) => {
      const obj = {}
      row.forEach((item, index) => {
        obj[columns[index] ? columns[index].replace('.', '') : ''] = item
        // eslint-disable-next-line no-underscore-dangle
        obj.__id = `${dataIndex}`
      })
      rowData2.push(obj)
    })

    const widthHeader = 160 * columns.length
    return (
      <AutoResizer>
        {({ width, height }) => (
          <BaseTable
            data={rowData2}
            width={widthHeader > width ? widthHeader : width}
            height={height}
            rowHeight={32}
          >
            {columns.map((item, index) => (
              <Column
                flexGrow={1}
                flexShrink={0}
                key={item.replace('.', '')}
                dataKey={item.replace('.', '')}
                width={160}
                title={item}
                rowKey="__id"
                // resizable={index < columns.length - 1}
                cellRenderer={({ cellData }) => (
                  <div title={cellData} className={styles.cell_cont}>{cellData}</div>
                )}
                headerRenderer={({
                  column,
                }) => (
                  <div title={column?.title} className={styles.cell_cont}>{column?.title}</div>
                )}
              />
            ))}
          </BaseTable>
        )}
      </AutoResizer>
    )
  }
}

class Logger extends PureComponent {
  state = {
    height: 42,
    newHeight: 300,
  };

  logRef = React.createRef();

  componentDidMount() {
    Bus.addListener('iconUpFn', this.iconUpCallBack)
    $(document.getElementsByTagName('html')[0]).keypress((e) => {
      if (e.ctrlKey && e.which === 17) {
        this.state.height === 42 ? this.iconUpFn() : this.iconDownFn()
      }
    })
  }

  componentWillReceiveProps(nextProps) {
    // 判断当前是否需要滚动，如果滚动条在最下面的话，则需要滚动
    const logger = this.logRef.current
    if (!logger) return
    const offsetHeight = logger.offsetHeight
    const scrollTop = logger.scrollTop
    const scrollHeight = logger.scrollHeight
    if (offsetHeight + scrollTop === scrollHeight) {
      // 为了react渲染之后再滚动，消除fiber的影响
      this.setState({}, () => {
        logger.scrollTop = logger.scrollHeight
      })
    }
  }

  componentWillUnmount() {
    Bus.removeListener('iconUpFn', this.iconUpCallBack)
    this.setState = (state, callback) => {

    }
  }

  menus = (item, k) => (
    <Menu>
      {item.key !== 'logger' && (
        <Menu.Item
          key="1"
          onClick={(event) => {
            this.props.onEdit(k)
            event.domEvent.stopPropagation()
          }}
        >
          关闭
        </Menu.Item>
      )}
      <Menu.Item
        key="2"
        onClick={(event) => {
          if (this.props.results.length !== 1) {
            if (item.key !== 'logger') {
              this.props.resultssChange([this.props.results[0], item], '1')
            } else {
              this.props.resultssChange([this.props.results[0]], '0')
            }
          }
        }}
      >
        关闭其他
      </Menu.Item>
      {item.key !== 'logger' && (
        <Menu.Item
          key="4"
          onClick={(event) => {
            if (this.props.results.length !== 1) {
              this.props.resultssChange([this.props.results[0]], '0')
            }
            event.domEvent.stopPropagation()
          }}
        >
          关闭全部
        </Menu.Item>
      )}
    </Menu>
  )

  iconUpCallBack = (taskId) => {
    if (taskId === this.props.taskId) {
      this.iconUpFn()
    }
  }

  iconDownFn() {
    this.setState(
      {
        height: 42,
      },
      () => {
        Bus.emit('editorLayout', this.props.taskId)
      },
    )
  }

  iconUpFn() {
    const { newHeight } = this.state
    this.setState(
      {
        height: newHeight < 100 ? 300 : newHeight,
      },
      () => {
        Bus.emit('editorLayout', this.props.taskId)
      },
    )
  }

  render() {
    const {
      results, activeKey, jobId, className, center,
    } = this.props
    const { height } = this.state
    const clientHeight = document.documentElement.clientHeight
    return (
      <ResizableBox
        className={`${styles.box_log} ${className}`}
        axis="x"
        height={height}
        width={Infinity}
        minConstraints={[Infinity, 33]}
        maxConstraints={[Infinity, clientHeight - 200]}
        onResize={(e) => {
          const h = clientHeight - e.clientY
          if (h > 33 && h < clientHeight - 200) {
            this.setState(
              {
                height: h,
                newHeight: h,
              },
              () => {
                if (this.state.style !== 'flow') {
                  Bus.emit('editorLayout', this.props.taskId)
                }
              },
            )
          } else if (h < 42) {
            this.setState(
              {
                height: 42,
              },
              () => {
                if (this.state.style !== 'flow') {
                  Bus.emit('editorLayout', this.props.taskId)
                }
              },
            )
          }
        }}
      >
        <div
          className={styles.editor_logger}
          onClick={(event) => {
            event.nativeEvent.stopImmediatePropagation()
          }}
        >
          <div className={`${styles.logger_box} ${this.props.theme}` || ''}>
            {results
              && results.length
              && jobId
              && activeKey != 0
              && results[activeKey] ? (
              // eslint-disable-next-line react/jsx-indent
              <div>
                <Tooltip
                  className={styles.tips}
                  placement="topRight"
                  title="通过SQL查询只显示前10000条"
                >
                  <i className="iconfont icon-tishi" />
                </Tooltip>
                <a
                  className={styles.download}
                  href={`${window.suanpan}/api/v1/offlineDev/task/result/download?jobId=${results[activeKey].jobId
                    // eslint-disable-next-line indent
                    }&result=${results[activeKey].result
                    // eslint-disable-next-line indent
                    }&projectId=${getProjectId()}`}
                  download
                >
                  <i className="iconfont-colour2 icon-excel1" />
                  <span>下载</span>
                </a>
              </div>
              // eslint-disable-next-line indent
            ) : null}
            <span className={styles.icon_up} onClick={this.iconUpFn.bind(this)}>
              <i className="iconfont icon-zhankai1-copy" />
            </span>
            <span className={styles.icon_down} onClick={this.iconDownFn.bind(this)}>
              <i className="iconfont icon-shouqi1-copy" />
            </span>
            <Tabs
              onChange={this.props.activeKeyonChange}
              activeKey={activeKey}
              type="editable-card"
              onEdit={this.props.onEdit}
              hideAdd
            >
              {results
                && results.map((obj, k) => (
                  <TabPane
                    forceRender={false}
                    tab={
                      <Dropdown
                        overlay={this.menus(obj, k)}
                        trigger={['contextMenu']}
                        style={{ float: 'left' }}
                      >
                        <div style={{ height: '100%', float: 'left' }}>
                          {k === 0 ? (
                            obj.name
                          ) : (
                            <Tooltip
                              placement="topLeft"
                              title={obj.sql}
                              mouseEnterDelay={1}
                              arrowPointAtCenter
                            >
                              {obj.name}
                            </Tooltip>
                          )}
                        </div>
                      </Dropdown>
                    }
                    // tab={obj.name}
                    key={k}
                    closable={obj.key !== 'logger'}
                  >
                    <div
                      className={styles.logger_content_box}
                      style={{
                        padding: '.2rem',
                      }}
                    >
                      {obj.key === 'logger' ? ( // 运行日志
                        obj.value.map((log, key) => <p key={key}>{log}</p>)
                      ) : (
                        <div
                          className={styles.table_box}
                        >
                          <LoggerTable
                            rowData={obj.value}
                            columns={obj.value[0]}
                            height={height}
                          />
                        </div>
                      )}
                    </div>
                  </TabPane>
                ))}
              {center || null}
            </Tabs>
          </div>
        </div>
      </ResizableBox>
    )
  }
}

export default Logger
